﻿using System;
using System.Diagnostics.CodeAnalysis;

using NUnit.Framework;

namespace SpellOutCheckAmount.Tests
{
    [SuppressMessage("Microsoft.StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented", Justification = "Reviewed. Suppression is OK here.")]
    [TestFixture]
    public class CheckAmountTests
    {
        [TestCase]
        public void TestConstructor()
        {
            Assert.IsNotNull(new CheckAmount(0m));
        }

        [TestCase]
        public void TestDigits()
        {
            Assert.AreEqual("Zero dollars", new CheckAmount(0m).ToString());
            Assert.AreEqual("One dollars", new CheckAmount(1m).ToString());
            Assert.AreEqual("Two dollars", new CheckAmount(2m).ToString());
            Assert.AreEqual("Three dollars", new CheckAmount(3m).ToString());
            Assert.AreEqual("Four dollars", new CheckAmount(4m).ToString());
            Assert.AreEqual("Five dollars", new CheckAmount(5m).ToString());
            Assert.AreEqual("Six dollars", new CheckAmount(6m).ToString());
            Assert.AreEqual("Seven dollars", new CheckAmount(7m).ToString());
            Assert.AreEqual("Eight dollars", new CheckAmount(8m).ToString());
            Assert.AreEqual("Nine dollars", new CheckAmount(9m).ToString());
        }

        [TestCase]
        public void TestTeens()
        {
            Assert.AreEqual("Ten dollars", new CheckAmount(10m).ToString());
            Assert.AreEqual("Eleven dollars", new CheckAmount(11m).ToString());
            Assert.AreEqual("Twelve dollars", new CheckAmount(12m).ToString());
            Assert.AreEqual("Thirteen dollars", new CheckAmount(13m).ToString());
            Assert.AreEqual("Fourteen dollars", new CheckAmount(14m).ToString());
            Assert.AreEqual("Fifteen dollars", new CheckAmount(15m).ToString());
            Assert.AreEqual("Sixteen dollars", new CheckAmount(16m).ToString());
            Assert.AreEqual("Seventeen dollars", new CheckAmount(17m).ToString());
            Assert.AreEqual("Eighteen dollars", new CheckAmount(18m).ToString());
            Assert.AreEqual("Nineteen dollars", new CheckAmount(19m).ToString());
        }

        [TestCase]
        public void TestTens()
        {
            Assert.AreEqual("Twenty dollars", new CheckAmount(20m).ToString());
            Assert.AreEqual("Thirty dollars", new CheckAmount(30m).ToString());
            Assert.AreEqual("Forty dollars", new CheckAmount(40m).ToString());
            Assert.AreEqual("Fifty dollars", new CheckAmount(50m).ToString());
            Assert.AreEqual("Sixty dollars", new CheckAmount(60m).ToString());
            Assert.AreEqual("Seventy dollars", new CheckAmount(70m).ToString());
            Assert.AreEqual("Eighty dollars", new CheckAmount(80m).ToString());
            Assert.AreEqual("Ninety dollars", new CheckAmount(90m).ToString());
        }

        [TestCase]
        public void TestTwoDigitsNumbers()
        {
            Assert.AreEqual("Twenty-one dollars", new CheckAmount(21m).ToString());
            Assert.AreEqual("Thirty-two dollars", new CheckAmount(32m).ToString());
            Assert.AreEqual("Forty-three dollars", new CheckAmount(43m).ToString());
            Assert.AreEqual("Fifty-four dollars", new CheckAmount(54m).ToString());
            Assert.AreEqual("Sixty-five dollars", new CheckAmount(65m).ToString());
            Assert.AreEqual("Seventy-six dollars", new CheckAmount(76m).ToString());
            Assert.AreEqual("Eighty-seven dollars", new CheckAmount(87m).ToString());
            Assert.AreEqual("Ninety-eight dollars", new CheckAmount(98m).ToString());
        }

        [TestCase]
        public void TestCents()
        {
            Assert.AreEqual("Zero and 10/100 dollars", new CheckAmount(0.1m).ToString());
            Assert.AreEqual("Five and 25/100 dollars", new CheckAmount(5.25m).ToString());
            Assert.AreEqual("Fifty-five and 99/100 dollars", new CheckAmount(55.99m).ToString());
        }

        [TestCase]
        public void TestHundreds()
        {
            Assert.AreEqual("One hundred dollars", new CheckAmount(100m).ToString());
            Assert.AreEqual("Five hundred dollars", new CheckAmount(500m).ToString());
            Assert.AreEqual("Seven hundred sixty-five dollars", new CheckAmount(765m).ToString());
            Assert.AreEqual("Nine hundred ninety-nine and 46/100 dollars", new CheckAmount(999.46m).ToString());
        }

        [TestCase]
        public void TestThousands()
        {
            Assert.AreEqual("One thousand dollars", new CheckAmount(1000m).ToString());
            Assert.AreEqual("One thousand forty-five dollars", new CheckAmount(1045m).ToString());
            Assert.AreEqual("Two thousand five hundred twenty-three and 04/100 dollars", new CheckAmount(2523.04m).ToString());
            Assert.AreEqual("Nine thousand nine hundred ninety-nine and 99/100 dollars", new CheckAmount(9999.99m).ToString());
        }

        [TestCase]
        [ExpectedException(typeof(NotSupportedException))]
        public void TestNotSupportedBigNumbers()
        {
            new CheckAmount(10000m).ToString();
        }

        [TestCase]
        [ExpectedException(typeof(NotSupportedException))]
        public void TestNotSupportedNegativeNumbers()
        {
            new CheckAmount(-1m).ToString();
        }
    }
}